package yns.springboot.guide.demo.data.mongodb.driver;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.mongodb.MongoClientSettings;
import com.mongodb.MongoClientSettings.Builder;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Sorts;

import yns.springboot.guide.demo.configure.data.mongodb.MongoClientConfigure;
import yns.springboot.guide.demo.configure.data.mongodb.MongoClientWithSettingsConfigure;

@Configuration
public class MongodbDriverFactory {
		 
	// 官方文档
	// https://www.mongodb.com/zh-cn/docs/drivers/java/sync/current/

	@Autowired
	private MongoClientConfigure mongoClientConfigure;
	
	@Autowired
	private MongoClientWithSettingsConfigure mongoClientWithSettingsConfigure;

	@Bean
	@Primary
	public MongoClient mongoClientFactory() {
		return MongoClients.create(mongoClientConfigure.getUri());
	}

	@Bean
	public MongoDatabase mongoDatabaseFactory() {
		return mongoClientFactory().getDatabase(mongoClientConfigure.getDatabase());
	}
	
	//@Bean("mongoClientWithSettings")
	public MongoClient mongoClientWithSettingsFactory() {
		return MongoClients.create(builderMongoClientSettings());
	}
	
	// 根据需要补充设置
	private MongoClientSettings builderMongoClientSettings() {
		
		Builder mongoClientSettingsBuilder = MongoClientSettings.builder();
		
		
		// hosts
		String[] serverAddressArray = mongoClientWithSettingsConfigure.getHosts().split(",");
		
		List<ServerAddress> hosts = new ArrayList<ServerAddress>();
		
		for (int i = 0; i < serverAddressArray.length; i++) {
			String eachServerAddress = serverAddressArray[i];
			
			String[] serverInfo = eachServerAddress.split(":");
			ServerAddress serverAddress = new ServerAddress(serverInfo[0], Integer.parseInt(serverInfo[1]));
		 	
		 	hosts.add(serverAddress);
		}
		
		// credential
		String userName = mongoClientWithSettingsConfigure.getUserName();
		String database = mongoClientWithSettingsConfigure.getDatabase();
		String password = mongoClientWithSettingsConfigure.getPassword();
		
		MongoCredential credential = MongoCredential.createCredential(userName, database, password.toCharArray());

		
		mongoClientSettingsBuilder.credential(credential)
				.applyToSslSettings(builder -> builder.enabled(true))
				.applyToClusterSettings(builder -> builder.hosts(hosts));
	    
		return mongoClientSettingsBuilder.build();
		
	}

	
	

	public static void main(String[] args) {
		// Connect to a Standalone MongoDB Instance
		MongoClientURI connection_Standalone = new MongoClientURI("mongodb://host1:27017");
		// Connect to a Replica Set
		MongoClientURI connection_ReplicaSet = new MongoClientURI("mongodb://host1:27017,host2:27017,host3:27017");
		MongoClientURI connection_ReplicaSet2 = new MongoClientURI("mongodb://host1:27017,host2:27017,host3:27017/?replicaSet=myReplicaSet");
		// Connection Options
		MongoClientURI connection_TLSandSSL = new MongoClientURI("mongodb://user1:pwd1@host1/?authSource=db1&ssl=true");
		MongoClientURI connection_DbUser = new MongoClientURI("mongodb://user1:pwd1@host1/?authSource=db1");
		// Compression
		// Snappy: Snappy compression can be used when connecting to MongoDB servers starting with the 3.4 release.
		MongoClientURI connection_CompressionSnappy = new MongoClientURI("mongodb://localhost/?compressors=snappy");
		// Zlib: Zlib compression can be used when connecting to MongoDB servers starting with the 3.6 release.
		MongoClientURI connection_CompressionZlib = new MongoClientURI("mongodb://localhost/?compressors=zlib");
		// Zstandard: Zstandard compression can be used when connecting to MongoDB servers starting with the 4.2 release.
		MongoClientURI connection_CompressionZstd = new MongoClientURI("mongodb://localhost/?compressors=zstd");
		
		String MONGODB_DATABASE = "testdb";
		String MONGODB_COLLECTION = "test";
		
		MongoClient mongoClient = MongoClients.create("mongodb://192.168.3.14:27017");
		MongoDatabase database = mongoClient.getDatabase(MONGODB_DATABASE);
		MongoCollection<Document> collection = database.getCollection(MONGODB_COLLECTION);

		Document doc = new Document("name", "MongoDB").append("type", "database").append("count", 1)
				.append("versions", Arrays.asList("v5.6","v3.2", "v3.0", "v2.6"))
				.append("info", new Document("x", 203).append("y", 102))
		        .append("time", LocalDateTime.now().toString());

		System.out.println(collection.countDocuments());
		
		List<Document> results  = new ArrayList<Document>();
		collection.find().sort(Sorts.descending("_id")).into(results);
		for (Document result : results) {
		      System.out.println(result.toJson());
		}
		
//		collection.insertOne(doc);
		// System.out.println(collection.find().first().toJson());
	}

}
